package com.halflife.framework.generator.template.mapper;

import com.halflife.framework.generator.GenerateUtil;
import com.halflife.framework.generator.annotation.Join;
import com.halflife.framework.generator.annotation.QueryAnn;
import org.apache.commons.lang.StringUtils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by zhaoyf on 2018/6/18.
 */
public class ResultMapAnalysis extends BaseAnalysis {
    public ResultMapAnalysis(Class clazz) {
        super(clazz);
    }

    @Override
    protected void setPrefix() {
        this.xmlStr.append( "<resultMap id=\"BaseResultMap\" type=\"" + this.clazz.getName() + "\">\n");
        for (Field field : fields) {
            if (field.getType().getPackage().getName().indexOf("com.halflife") == -1){

            }
        }

    }
    private String getAlias(String name) {
        if (!joinMap.containsKey(name)) {
            return name;
        }
        for(int i=0;i<10;i++) {
            if (joinMap.containsKey(name + i)) {
                continue;
            }
            return name+i;
        }
        return name;
    }
    private Map<String,String> joinMap = new HashMap<>();

    protected void fieldAnaysis1() {
        this.fieldStrs = new StringBuilder();
        this.joinStrs = new StringBuilder();
        final int[] len = {0};
        String prefix = prefixs[objs];
        QueryAnn classAnn =(QueryAnn) this.clazz.getAnnotation(QueryAnn.class);
        this.joinStrs.append("`").append(classAnn.table()).append("` ");
        this.joinStrs.append(prefix);
        for (Field field : fields) {
            if (field.getType() == List.class) {
                continue;
            }

            CustomField customField = new CustomField(field);
            if (field.getType().getPackage().getName().indexOf("com.halflife") == -1){
                String str = this.getValue1(customField);
                xmlStr.append("\t");
                xmlStr.append(str);
                len[0] += str.length();
                if (customField.isPersist()) {
                    this.setFieldStr(field,prefix);
                }
            }else{
                Join join = field.getAnnotation(Join.class);
                if (join!=null) {
                    rootField = field;
                    if(StringUtils.isNotBlank(join.join())){
                        String[] joins = join.join().split(";|；|,|，");
                        for (String joinstr : joins) {
                            String[] singleJoins = joinstr.split(":|：");
                            this.nextJoinMap.put(singleJoins[0], GenerateUtil.getJoinCondition(singleJoins.length>1?singleJoins[1]:""));
                        }
                    }
                    String alias = getAlias(field.getName());
                    joinMap.put(field.getName(), field.getName());
                    this.setJoinStr(field,prefix,alias,GenerateUtil.getJoinCondition(join.joinType()));
                    xmlStr.append("<association property=\""+field.getName()+"\"");
                    xmlStr.append("   javaType=\"" + field.getType().getName() + "\">\n");
                    this.fillField(field,alias,"");
                    xmlStr.append("</association>");
                }
            }
            //value==null 说明是特殊字段
            xmlStr.append(this.getLineSuffix(len));
        }
    }


    private Map<String, String> nextJoinMap = new HashMap<>();
    private Field rootField;

    private void fillField(Field field,String prefix,String linkStr) {
        //todo
        Class c = field.getType();
        Field[] fields = c.getDeclaredFields();
        for (Field f : fields) {
            CustomField customField = new CustomField(f);
            if (f.getType().getPackage().getName().indexOf("com.halflife") == -1){
                if (customField.isRefered()){
                    String str = this.getValue1(customField,prefix);
                    xmlStr.append("\t");
                    xmlStr.append(str);
                    xmlStr.append("\n");
                    this.setFieldStr(f,prefix);
                }
            }else {
                String _linkStr = StringUtils.isBlank(linkStr) ? f.getName() :( linkStr + "." + f.getName());
//                String _root = rootField.getName()+"."+(StringUtils.isBlank(linkStr) ? "" :( linkStr + "." ));
                String _root = "";
                if (nextJoinMap.containsKey(_linkStr)) {
                    String alias = getAlias(f.getName());
                    this.setJoinStr(f,prefix,alias,nextJoinMap.get(_linkStr));
                    xmlStr.append("<association property=\""+_root+f.getName()+"\"");
                    xmlStr.append("  javaType=\"" + f.getType().getName() + "\">\n");
                    this.fillField(f,alias,_linkStr);
                    xmlStr.append("</association>\n");
                }
            }

        }
//        System.out.println(this.joinStrs.toString());
    }
    protected String getValue1(CustomField customField) {
        if (!customField.isPersist()) {
            return "";
        }
        return this.getValue1(customField,"");
    }
    private void setJoinStr(Field field,String left,String right,String joinstr) {
        QueryAnn ann = field.getAnnotation(QueryAnn.class);
        Join join = field.getAnnotation(Join.class);
        this.joinStrs.append(" ").append(joinstr).append(" ");
        QueryAnn classAnn =(QueryAnn) field.getType().getAnnotation(QueryAnn.class);
        this.joinStrs.append("`");
        this.joinStrs.append(classAnn.table());
        this.joinStrs.append("` ");
        this.joinStrs.append(right);
        this.joinStrs.append(" on ");
        this.joinStrs.append(left).append(".").append(StringUtils.isNotBlank(ann.custormName())?ann.custormName():(field.getName()+"Id"));
        this.joinStrs.append("=").append(right).append(".").append("id");
    }
    private boolean fieldStr_first = true;
    private int fieldLength =0;
    private void setFieldStr(Field field,String prefix) {
        if (fieldStr_first) {
            fieldStr_first = false;
        }else{
            this.fieldStrs.append(",");
        }
        fieldLength =  (prefix+"."+field.getName()).length()+fieldLength;
        if (fieldLength > 100) {
            this.fieldStrs.append("\n");
            this.fieldLength = 0;
        }
        this.fieldStrs.append(prefix).append(".").append(field.getName());
        if (!prefix.equals("t")) {
            this.fieldStrs.append(" as ").append(prefix).append("_").append(field.getName());
        }
    }

    protected String getValue1(CustomField customField,String prefix) {
        String prefix_ = StringUtils.isBlank(prefix)?"":prefix+"_";
        StringBuilder sb = new StringBuilder();
//        System.out.println(customField.getName());
        if (customField.getName().equals("id")) {
            sb.append("<id column=\"").append(prefix_).append(customField.getName()).append("\" jdbcType=\"").append(customField.getTypeName().toUpperCase()).append("\" property=\"").append(customField.getName()).append("\"/>");
        } else if(StringUtils.isNotBlank(customField.getTypeName()))
            sb.append("<result column=\"").append(prefix_).append(customField.getName()).append("\" jdbcType=\"").append(customField.getTypeName().toUpperCase()).append("\" property=\"").append(customField.getName()).append("\"/>");
        return sb.toString();
    }

    protected String getLineSuffix(int[] len) {
        return "\n";
    }

    ;

    protected void setSuffix() {

        this.xmlStr.append( " </resultMap>");
    }

    ;
}
